package com.eairlv.utils.validator.url;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.eairlv.utils.MSInterceptorProperties;
import com.eairlv.utils.config.MSInterceptor;
import com.eairlv.utils.utils.LogUtil;
import com.eairlv.utils.validator.user.UserInformation;
import com.eairlv.utils.validator.user.UserValidator;
import io.undertow.server.HttpServerExchange;
import io.undertow.servlet.spec.HttpServletRequestImpl;
import io.undertow.util.HttpString;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.RequestFacade;
import org.apache.tomcat.util.http.MimeHeaders;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;

/**
 * @author eairlv
 * @description
 * @date 11:26 2019/8/27
 */
@Slf4j
public class UrlValidator {

    /**
     * undertow容器
     */
    public static final String UNDERTOW = "io.undertow.servlet.spec.HttpServletRequestImpl";

    /**
     * tomcat容器
     */
    public static final String TOMCAT = "org.apache.catalina.connector.RequestFacade";

    /**
     * 用户身份标识
     */
    public static final String GATEWAY_AUTHORIZATION = "Gateway-Authorization";

    /**
     * URL权限验证器
     * @param request
     * @param restTemplate
     * @param properties
     * @return
     */
    public static Boolean valid(HttpServletRequest request, RestTemplate restTemplate, MSInterceptorProperties properties){
        UserInformation userInformation = UrlClient.jwt(request.getMethod(), request.getRequestURI(), request.getHeader(GATEWAY_AUTHORIZATION), restTemplate, properties);
        if (userInformation != null){
            if (userInformation.getOpenId() != null){
                if (properties.getUserPayload().equals(UserValidator.HEADER)){
                    try {
                        if (Class.forName(UNDERTOW) != null && request instanceof HttpServletRequestImpl){
                            ((HttpServerExchange)ReflectUtil.getFieldValue(request, "exchange"))
                                    .getRequestHeaders().add(new HttpString(UserValidator.USER_INFORMATION), JSON.toJSONString(userInformation));
                        }
                    } catch (Exception e){
                        log.warn("undertow container error", LogUtil.getExceptionMessage(e));
                    }
                    try {
                        if (Class.forName(TOMCAT) != null && request instanceof RequestFacade){
                            Request req = (Request) ReflectUtil.getFieldValue(request, "request");
                            org.apache.coyote.Request creq = (org.apache.coyote.Request) ReflectUtil.getFieldValue(req, "coyoteRequest");
                            MimeHeaders headers = (MimeHeaders) ReflectUtil.getFieldValue(creq, "headers");
                            headers.addValue(UserValidator.USER_INFORMATION).setString(JSON.toJSONString(userInformation));
                        }
                    } catch (Exception e){
                        log.warn("tomcat container error", LogUtil.getExceptionMessage(e));
                    }
                } else {
                    MSInterceptor.USER_INFORMATION.set(userInformation);
                }
            }
            return Boolean.TRUE;
        } else {
            return Boolean.FALSE;
        }
    }
}
